home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: netcom.com!marnold
- From: marnold@netcom.com (Matt Arnold)
- Subject: Re: Aborting Constructors, Part II
- Message-ID: <marnoldDM529E.3CH@netcom.com>
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
- References: <4eoeck$t6n@news.ios.com> <4eq99t$fpu@fsuj01.rz.uni-jena.de>
- Date: Fri, 2 Feb 1996 08:00:26 GMT
- Sender: marnold@netcom7.netcom.com
-
- mkt@isun04.inf.uni-jena.de (Tilo Koerbs) writes:
-
- >> test::test(){
- >> cout << "constructing object\n";
- >> delete this;
- >> throw(xmsg(string("deleted the object!\n")));
- >> }
-
- >I am sure that using delete on this is not allowed in C++.
-
- That is not correct. It is allowed and, while some folks dislike it on
- a conceptual basis, it can be a quite useful capability for objects to
- destroy themselves.
-
- However, you are correct if you mean to say that using "delete this"
- in the above code is not *proper*. It is certainly legal code, but it
- will likely not function correctly. It's simply wrong and here are
- three good reasons why...
-
- Problem 1: What if a "test" object was allocated on the stack or as a
- static object, and then the constructor failed? delete would be passed
- an address that obviously didn't come from the heap. This would probably
- have the effect of corrupting the heap, or immediately crashing the
- program.
-
- Problem 2: The language already provides an automatic call to delete
- iff you throw an exception from an object that was allocated using new.
- The code above would cause delete to be called twice! Once again, heap
- corruption is likely.
-
- Problem 3: In the general case, calling "delete this" from the ctor is
- not correct (not only because of the above two problems), but because
- "delete this" will cause the destructor (test::~test) to be called. The
- destructor is likely to behave incorrectly since it only expects to get
- called for a successfully constructed object. If you call "delete this"
- in the midst of a constructor, the destructor will attempt to destory an
- only *partially* valid object! That's a recipe for trouble, for sure.
-
- NOTE: If you are thinking that Problem 2 doesn't look right because it
- says that the compiler calls delete for you, don't worry. It does not
- introduce the same issues as in Problem 3 because, when the compiler
- automatically calls delete for you, it is *only* to free the memory.
- Conceptually, the compiler generates code something like this...
-
- delete((void*)this);
-
- ...and no destructor is called. Only memory is freed.
-
- In short, the "delete this" is the above code is not only unnecessary, it's
- just plain wrong.
-
- >I can remember that Borland is a little bit strange in those things.
-
- Really? So far, Boralnd has had one of the most robust and up-to-date C++
- implementations available for the PC, if anywhere. If you mean to say that
- Borland is strange for allowing "delete this", you are wrong. Any C++
- compiler would be in error if it did not allow you to write "delete this".
-
- >They allow a 'return 0' in constructors if the object cannot be constructed
- >and something else.
-
- Constructors cannot return values. Borland C++ does not allow constructors
- to return a value.
-
- >While running a member function one cannot delete the object the function
- >is working on. After the delete the object the function works with is
- >not valid any more. So what is the function working with?
-
- Yes, the programmer must be careful not to reference an object (internally
- or externally) after it has been deleted, but that is always the case, right?
- Obviously. Yet, it is not illegal to use "delete this". Even if "delete
- this" were not allowed, you could still do...
-
- void Object::KillMyself()
- {
- Object* pobj = this;
-
- delete pobj;
- }
-
- It's not "delete this", but does exactly the same thing.
-
- Sure, "delete this" is dangerous if the programmer doesn't realize what is
- going on, and refers to an object after it has been destoryed. However, if
- you find yourself using "delete this" without realizing what you are doing,
- your C++ skills need some more work, IMO.
-
- If you don't like the "delete this" construct (as some poeple don't), then
- simply don't use it, and you'll never have to worry about the mistakes you
- might make with it.
-
- >The output is absolutely correct (if the program not crashes, which is a valid
- >behaviour in such cases).
-
- >But why can't you abort the constructor without this delete?
- >Before throwing the exception you can free all dynamically (inside the
- >constructor) created things.
-
- I've lost track of what you are trying to say here (pehaps some text is
- missing from a previous posting), but your initial points regarding what
- is or is not legal in C++ are not correct.
-
- I think the original poster assumed that "delete this" was the proper thing
- to do when throwing an exception from a ctor. But, because of at least the
- three problems above, it is not. The langauge already provides a way for a
- partially constructed object to be partially deconstructed in such cases (as
- well as for the memory used for the dynamically allocated object to be freed
- automatically).
-
- There are many excellent C++ books that describe how exceptions work and
- can be used, even in the presence of dynamically allocated memory and from
- within constructors.
-
- Regards,
- -------------------------------------------------------------------------
- Matt Arnold | | ||| | |||| | | | || ||
- marnold@netcom.com | | ||| | |||| | | | || ||
- Boston, MA | 0 | ||| | |||| | | | || ||
- 617.389.7384 (h) 617.576.2760 (w) | | ||| | |||| | | | || ||
- C++, MIDI, Win32/95 developer | | ||| 4 3 1 0 8 3 || ||
- -------------------------------------------------------------------------
-